package com.lonni.rpc.core.socket.codec;

import com.lonni.rpc.core.serialize.IRpcSerialize;
import com.lonni.rpc.core.serialize.SerializeFactory;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.MessageToByteEncoder;
import lombok.extern.slf4j.Slf4j;

import java.io.Serializable;

/**
 * 消息编码器
 * 将消息对象转换为二进制
 *
 * @author: Lonni
 * @date: 2024/7/8 0008 16:27
 */
@Slf4j
public class RpcProtocolEncoder extends MessageToByteEncoder<RpcProtocol<Object>> {


    @Override
    protected void encode(ChannelHandlerContext channelHandlerContext, RpcProtocol<Object> rpcProtocol, ByteBuf byteBuf) throws Exception {
        //标记当前位置,用于回退
        byteBuf.markWriterIndex();
        RpcProtocolHeader header = rpcProtocol.getHeader();
        byteBuf.writeShort(header.getMagic());
        byteBuf.writeByte(header.getVersion());
        byteBuf.writeByte(header.getMsgType());
        byteBuf.writeByte(header.getStatus());
        byteBuf.writeLong(header.getRequestId());
        byteBuf.writeInt(header.getSerializationType());

        //写入消息体
        //序列化 TODO 后期增加SPI机制加载用户自定义序列化工具
        IRpcSerialize serialize = SerializeFactory.getSerialize(String.valueOf(header.getSerializationType()));
        if (serialize == null) {
            log.error("Netty编码器执行失败,类型为[{}]的序列化器为空!", header.getSerializationType());
            byteBuf.resetWriterIndex();
            return;
        }
        byte[] bodyBytes = serialize.serialize(rpcProtocol.getBody());
        byteBuf.writeInt(bodyBytes.length);
        byteBuf.writeBytes(bodyBytes);
        log.info("Netty编码完成");
    }
}



